<?php
declare (strict_types=1);

namespace app\course\logic\video\admin;

use app\admin\logic\system\Log;
use app\common\exception\LogicException;
use app\course\event\subscribes\course\ExamineNotify;
use app\course\event\subscribes\video\admin\Video as VideoEvevt;
use app\course\logic\record\admin\LearnRecord;
use app\course\model\video\admin\Video as VideoModel;
use app\course\model\video\admin\VideoSection as VideoSectionModel;
use app\course\model\video\CourseSectionVideo;
use app\school\model\school\School;
use think\facade\Event;

/**
 * 后台管理逻辑层
 */
class VideoSection extends VideoSectionModel
{

    /**
     * 课时列表
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-04-28
     *
     * @param    [type]                         $id  [description]
     * @param integer $pid [description]
     * @return   [type]                              [description]
     */
    public function sectionTree($id, $pid = 0)
    {
        $section_level = app(VideoModel::class)->where('id', $id)->value('section_level');
        $sectionTree   = $this->where(['course_id' => $id, 'pid' => $pid])->order(['best_sort' => 'ASC', 'id' => 'ASC'])->select();
        if ($sectionTree) {
            foreach ($sectionTree as $sec) {
                $sec->hasChildren     = $this->hasChildren($sec->id);
                $sec->video_sec_level = $section_level;
            }
        }

        return $sectionTree;
    }

    /**
     * 是否有子集
     * Author   亓官雨树<lucky.max@foxmail.com>
     * Date 2020-03-24
     */
    public function hasChildren(int $pid = 0): bool
    {
        return $this->where('pid', $pid)->find() ? true : false;
    }

    /**
     * 创建课程课时
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-04-27
     *
     * @param    [type]                         $id   [description]
     * @param    [type]                         $pid  [description]
     * @param    [type]                         $data [description]
     */
    public function addSection($id, $pid, $data)
    {
        $is_last = $this->isLastSction($id, $pid);

        $save = [
            'course_id'             => $id,
            'pid'                   => $pid,
            'level'                 => $this->getLevel($pid),
            'is_last'               => $is_last,
            'title'                 => $data['title'],
            // 'material_id'           => $data['material_id'] ?? 0,
            'completion_conditions' => $data['completion_conditions'] ?? 0,
            'class_hour'            => $data['class_hour'] ?? 0,
            'update_admin'          => request()->admin_user_id,
        ];

        // 验证数据
        $this->getValidate()->failException()->check($save);
        $this->startTrans();
        // 最后一级,保存课时数据
        try {
            if ($is_last) {
                $mhm_id = request()->user->getAttr('mhm_id');
                // 如果为机构审核操作, 则检测是否要进入平台审核流程
                if ($mhm_id != 1) {
                    $school = app(School::class)->where('id', $mhm_id)->findOrFail();
                    // 是否需要平台再审核 is_audit为1表示需要平台再审,此时状态改为3
                    $status = $school->getAttr('is_audit') == 1 ? 3 : 1;
                } else {
                    // 为平台审核操作直接通过
                    $status = 1;
                }
                if (!$data['course_data_id']) {
                    throw new LogicException("请完善课件信息");
                }
                $videoData = new CourseSectionVideo();

                $videoData->data_type = $data['course_data_type'];
                if ($data['course_data_type'] == 3) {
                    $videoData->attach_id = 0;
                    $videoData->data_txt  = $data['course_data_id'];
                } else {
                    $videoData->attach_id = $data['course_data_id'];
                    $videoData->data_txt  = '';
                }

                if (!$videoData->save()) throw new LogicException("新建课时失败");
                $save['course_data_id'] = $videoData->id;
                $save['price']          = $data['price'];
                $save['audition']       = $data['audition'];
                $save['status']         = $status;
            }

            if (!$this->save($save)) {
                throw new LogicException("新建课时失败");
            }
            // 增加课时，重新计算用户进度
            if ($is_last) {
                $record = app(LearnRecord::class)->whereCourseId($id)->count();
                if ($record) {
                    Event::subscribe(VideoEvevt::class);
                    Event::trigger('SectionAdd', ['courseId' => $id]);
                }
            }

            $this->commit();
            $course_title = app(VideoModel::class)->where('id', $id)->value('title');
            // 课时创建成功,发送管理员通知
            // 如果是平台或配置的机构不需要向平台审核,则不发
            if ($is_last && !request()->is_platform && $status == 3) {
                Event::subscribe(ExamineNotify::class);
                Event::trigger('ExamineNotify', [
                    'type' => 'examine',
                    'data' => [
                        'admin_user_id' => $mhm_id,
                        'sec_title'     => $course_title . ' - ' . $data['title'],
                        'status'        => 3
                    ]
                ]);
            }

            Log::write('新建点播课时【' . $course_title . ' - ' . $save['title'] . '】', 'video', 'create', true);

            return $this;

        } catch (LogicException $error) {
            $this->rollback();
            throw $error;
        }

    }

    /**
     * 编辑课时
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-04-27
     *
     * @param    [type]                         $section [description]
     * @param    [type]                         $data    [description]
     * @return   [type]                                  [description]
     */
    public function editSection($section, $data)
    {
        // 验证数据
        $this->getValidate()->failException()->check($data);

        $this->startTrans();
        try {
            // 机构用户所属机构ID
            $mhm_id = request()->user->getAttr('mhm_id');
            // 参数
            $section->title          = $data['title'];
            $section->price          = $data['price'];
            $section->audition       = $data['audition'];
            $section->update_admin   = $mhm_id == 1 ? $section->update_admin : request()->admin_user_id;
            $section->update_teacher = $mhm_id == 1 ? $section->update_teacher : 0;

            // 课时
            $is_last = $this->isLastSction($section->getAttr('course_id'), $section->getAttr('pid'));

            if ($is_last) {
                if (!$data['course_data_id']) {
                    throw new LogicException("请完善课件信息");
                }
                $section->courseData->data_type = $data['course_data_type'];
                if ($data['course_data_type'] == 3) {
                    $section->courseData->attach_id = 0;
                    $section->courseData->data_txt  = $data['course_data_id'];
                } else {
                    $section->courseData->attach_id = $data['course_data_id'];
                    $section->courseData->data_txt  = '';
                }

                // $section->material_id           = $data['material_id'] ?? 0;
                $section->completion_conditions = $data['completion_conditions'] ?? 0;
                $section->class_hour            = $data['class_hour'] ?? 0;

                if (1 != $mhm_id) {
                    $school = app(School::class)->where('id', $mhm_id)->findOrFail();
                    // 是否需要平台再审核 is_audit为1表示需要平台再审,此时状态改为3
                    $section->status = $school->getAttr('is_audit') == 1 ? 3 : $section->status;
                }

                if (!$section->together(['courseData'])->save()) {
                    throw new LogicException("编辑课时失败");
                }

            } else {
                if (!$section->save()) {
                    throw new LogicException("编辑课时失败");
                }
            }
            $course_title = app(VideoModel::class)->where('id', $section->course_id)->value('title');
            // 平台审核发送通知
            if ($section->status == 3) {
                Event::subscribe(ExamineNotify::class);
                Event::trigger('ExamineNotify', [
                    'type' => 'examine',
                    'data' => [
                        'admin_user_id' => $mhm_id,
                        'sec_title'     => $course_title . ' - ' . $section->title,
                        'status'        => 3
                    ]
                ]);
            }

            Log::write('编辑点播课时【' . $course_title . ' - ' . $section->title . '】', 'video', 'update', true);
            $this->commit();
            return $section;
        } catch (LogicException $error) {
            $this->rollback();
            throw $error;
        }
    }

    /**
     * [isLastSction description]
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-04-27
     *
     * @param    [type]                         $id  [description]
     * @param    [type]                         $pid [description]
     * @return   int                             [description]
     */
    public function isLastSction($id, $pid)
    {
        $level         = $this->getLevel($pid);
        $section_level = app(VideoModel::class)->where('id', $id)->value('section_level');

        return $section_level == $level ? 1 : 0;
    }

    /**
     * 获取层级
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-04-28
     *
     * @param    [type]                         $pid [description]
     * @return   [type]                              [description]
     */
    public function getLevel($pid = 0)
    {
        $plevel = 0;
        $pid && $plevel = $this->where('id', $pid)->value('level');
        $level = $plevel + 1;

        return $level;
    }

    public function sectionDelete(int $id)
    {
        $section = $this->findOrFail($id);

        if ($this->hasChildren($id)) {
            throw new LogicException('存在下级，不能删除');
        }

        $course_title = app(VideoModel::class)->where('id', $section->course_id)->value('title');

        Log::write('删除点播课时【' . $course_title . ' - ' . $section->title . '】', 'video', 'delete', true);
        $re = $section->delete();
        // 删除课时后，删除用户学习记录，重新计算进度
        if ($re) {
            $record = app(LearnRecord::class)->whereCourseId($section->course_id)->count();
            if ($record) {
                Event::subscribe(VideoEvevt::class);
                Event::trigger('SectionDelete', ['courseId' => $section->course_id, 'sectionId' => $id]);
            }
        }
        return $re;
    }

    /**
     * 编辑指定字段
     * Author   亓官雨树<lucky.max@foxmail.com>
     * Date 2020-03-27
     */
    public function updateSort($id, $value)
    {
        // 信息
        $section = $this->findOrFail($id);

        $section->best_sort = $value;

        if (!$section->force()->save()) {
            throw new LogicException("更新失败");
        }

        // 返回值
        return $section;
    }
}
